﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Cache;
using System.IO;
using Task.Log;
using Task.DB;
using Task.Quartz.Execute.IExchange;
using Task.Util;
using System.Threading;
using System.Data;

namespace Task.Quartz.Execute.Holytax
{
    public class DownDate : ITaskExchange
    {
        private readonly Object lock_this_ = new Object();
        private SynParamEntity gogal = null;
        public void Run(SynParamEntity synParam)
        {
            try
            {

                this.gogal = synParam;
                for (int i = 0; i < 10; i++)
                {
                    NlogLogger.Default.Info("******任务【" + gogal.FileName + "-自动下载" + "】开始*****"
                   , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    Thread.Sleep(1000);
                }
                NlogLogger.Default.Info("******任务【" + gogal.FileName + "-自动下载" + "】开始*****"
                    , System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                //var Context = FluentDB.ContextSQL();
                //List<dynamic> account_EntList = Context.Sql(@"select * from Account_Ent where entid in(
                //                                    select distinct entid from Account_Ent2User 
                //                                    where LastReceiveTime <> ''
                //                                    )").QueryMany<dynamic>();
                //Run(account_EntList);
                Thread.Sleep(1000);

            }
            catch (Exception ex)
            {
                LogHelper.Info(ex.ToString(), System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            }
        }

        void Run(List<dynamic> List)
        {
            if (List.Count() <= 0)
            {
                LogHelper.Info("不存在需要处理任务，自动退出！" + gogal.FileName, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                return;
            }
            System.Threading.CancellationTokenSource cts = new System.Threading.CancellationTokenSource();
            System.Threading.Tasks.TaskFactory taskFactory = new System.Threading.Tasks.TaskFactory();
            List<System.Threading.Tasks.Task> taskList = new List<System.Threading.Tasks.Task>();

            foreach (var item in List)
            {
                var EntID = item.EntID;
                var EntTaxCode = item.EntTaxCode;
                taskList.Add(taskFactory.StartNew(() => TaskDo(cts.Token, EntID, EntTaxCode), cts.Token));
            }

            taskFactory.ContinueWhenAll(taskList.ToArray(),
                 TaskEnd
                , System.Threading.CancellationToken.None);
        }

        void TaskEnd(System.Threading.Tasks.Task[] tasks)
        {
            int loop = 0;
            foreach (System.Threading.Tasks.Task task in tasks)
            {
                if (task.IsCompleted)
                {
                    loop++;
                }
                else
                {
                    break;
                }
            }
            if (loop == tasks.Count())
            {
                LogHelper.Info("任务全部结束" + gogal.FileName, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            }
        }

        /// <summary>
        /// 执行函数需要有返回值
        /// </summary>
        /// <param name="ct"></param>
        /// <param name="InEntID"></param>
        /// <param name="InEntTaxCode"></param>
        /// <returns></returns>
        string TaskDo(System.Threading.CancellationToken ct, object InEntID, object InEntTaxCode)
        {
            lock (lock_this_)
            {
                try
                {

                    #region 数据处理

                    string savePath = string.Format(@"{0}\TempData\DownFile\", AppPathUtil.GetAssemblyDirPath());
                    if (!Directory.Exists(savePath))
                    {
                        Directory.CreateDirectory(savePath);
                    }

                    var Context = FluentDB.ContextSQL();
                    int numberOfaccount_EntList = Context.Sql("select count(pkid) from INV_VAT where buyer =@0 and statusId = '03' ").Parameters(InEntTaxCode).QuerySingle<int>();
                    if (numberOfaccount_EntList == 0)
                    {
                        LogHelper.Debug("税号【" + InEntTaxCode + "】无需要接收数据,自动退出。", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                        return null;
                    }

                    string EntID = InEntID.ToString();
                    string entTaxCode = InEntTaxCode.ToString();
                    dynamic Account_Ent2User = Context.Sql(@"select MIN(LastReceiveTime) as LastReceiveTime from Account_Ent2User 
                                                        left join Account_Ent on Account_Ent.entid = Account_Ent2User.entid 
                                                        Where Account_Ent.EntID = @0 ")
                                                      .Parameters(EntID).QuerySingle<dynamic>();
                    string startDate = Account_Ent2User.LastReceiveTime == null ? DateTime.Now.ToString("yyyyMMdd000000") : Account_Ent2User.LastReceiveTime;
                    string endDate = DateTime.Now.ToString("yyyyMMddHHmmss");
                    LogHelper.Info("处理税号=" + InEntTaxCode + " 时间" + startDate + "至" + endDate, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    ExchangeEntity exEntity = MemoryCacheHelper.GetCacheItem("key_TaskDo_" + entTaxCode, delegate ()
                    {
                        INIFileUtil ini = new INIFileUtil(AppDomain.CurrentDomain.BaseDirectory + "/Configs/config_Holytax.ini");
                        return new ExchangeEntity(entTaxCode,
                                        ini.IniReadValue("param", "PFAccount"),
                                        ini.IniReadValue("param", "PFPassword"),
                                        ini.IniReadValue("param", "ServerAddress") + ini.IniReadValue("param", "DownURL"),
                                        startDate,
                                        endDate,
                                        ini.IniReadValue("param", "IsProxy"),
                                        ini.IniReadValue("param", "ProxyIp"),
                                        ini.IniReadValue("param", "ProxyPort"),
                                        ini.IniReadValue("param", "AuthUID"),
                                        ini.IniReadValue("param", "AuthPassword"));
                    }, new TimeSpan(0, 60 * 60, 0));

                    exEntity.StartDate = startDate;
                    exEntity.EndDate = endDate;

                    string saveFileName = string.Format("{0}", entTaxCode + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + RandomValue.GetRandomNumber(6));
                    string zipfileName = string.Format("{0}\\{1}.zip", savePath, saveFileName);
                    //LogHelper.Debug("下载【" + entTaxCode + "】数据包", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    if (!InvoiceExchangeHelper.DownloadZips(exEntity, zipfileName))
                    {
                        LogHelper.Error(exEntity.ErrorDesc, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                        return null;
                    }

                    #region 处理下载的文件
                    int iUnZipResult = ZipHelper.UnZipFile(zipfileName, zipfileName.Replace(".zip", ""));
                    if (iUnZipResult != 1)
                    {
                        LogHelper.Error("解压失败！" + "【" + zipfileName + "】", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                        return null;
                    }

                    //解析Xml文件
                    string strXmlFilePath = Directory.GetFiles(string.Format("{0}\\{1}", savePath, saveFileName))[0];
                    VatReceiveEntity receiveEntity = new VatReceiveEntity();
                    string message = string.Empty;
                    //LogHelper.Debug("解析【" + entTaxCode + "】数据包", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    bool bReceive = receiveEntity.Analysis(strXmlFilePath, out message);
                    if (!bReceive)
                    {
                        LogHelper.Error(message, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                        return null;
                    }

                    StringBuilder sb = new StringBuilder();
                    string str = string.Empty;
                    foreach (var item in receiveEntity.InvoiceResultEntity)
                    {
                        sb.AppendFormat("发票代码:{0}，发票号码：{1}，发票状态:{2}\r\n", item.invoicecode, item.invoiceno, item.authstatus);
                    }
                    sb.AppendFormat("税号[{0}]处理完毕，共处理了{1}张发票，其中删除的{2}条，认证通过的{3}条，认证未通过的{4}条，无需认证的{5}条.\r\n",
                            entTaxCode, receiveEntity.CntAll, receiveEntity.CntInvalid, receiveEntity.CntAuthPass, receiveEntity.CntAuthNotPass, receiveEntity.CntNotNeedAuth);
                    LogHelper.Debug(sb.ToString(), System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

                    Context.Update("Account_Ent2User").Column("LastReceiveTime", endDate).Where("EntID", EntID).Execute();

                    Directory.Delete(zipfileName.Replace(".zip", ""), true);
                    File.Delete(zipfileName);
                    #endregion

                    #endregion

                    return null;
                }
                catch (Exception exe)
                {
                    LogHelper.Info(exe.Message, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    return null;
                }
            }
        }
    }
}
